import ResUrl from "../Res/ResUrl";
import LTRes from "../Res/LTRes";
import GlobalUnit from "../../script/common/GlobalUnit";
import SceneManager from "./SceneManager";


export interface node {
    name: string;
    child: node[] | Prefab[];
    position: string;
    euler: string;
    scale: string;
}

export interface Prefab {
    name: string;
    prefabName: string;
    position: string;
    euler: string;
    scale: string;
}

// 场景
export default class Scene {
    private _sceneConfig: node;
    private _prefabRes: string[] = [];
    private _scene: Laya.Sprite3D;

    // 所有预制体 根据预制体名字 查找或遍历初始化
    public prefabs: { [key: string]: Laya.Sprite3D[] } = {};

    constructor(sceneConfig: node) {
        this._sceneConfig = sceneConfig;
    }

    public get scene() {
        return this._scene.getChildAt(0) as Laya.Sprite3D;
    }

    public async loadRes() {
        await LTRes.LoadAsync(this.scenePrefabUrl());
    }

    // 构建场景
    public async buildScene(): Promise<Laya.Sprite3D> {
        if (this._scene) return this._scene;
        await this.loadRes();
        this._scene = new Laya.Sprite3D();
        GlobalUnit.s3d.addChild(this._scene);
        this._buildScene(this._sceneConfig, this._scene);
        return this._scene;
    }

    // 清除场景
    public clearScene() {
        if (this._scene) {
            this._scene.destroy();
            this._prefabRes = [];
            this.prefabs = {};
            this._scene = null;
        }
    }

    public scenePrefabResName(): string[] {
        if (!this._sceneConfig) { console.error("场景配置表 不存在"); return; }
        if (!this._prefabRes || this._prefabRes.length <= 0) {
            this._getPrefabName(this._prefabRes, this._sceneConfig)
        }
        return this._prefabRes;
    }

    public scenePrefabUrl() {
        let resUrl = [];
        let resName = this.scenePrefabResName();
        resName && resName.forEach((name: string) => {
            resUrl.push(ResUrl.prefab_url(name));
        })
        return resUrl;
    }

    private _buildScene(node: node | Prefab, parent: Laya.Sprite3D) {
        let prefabName = node["prefabName"];
        if (prefabName) {
            node = node as Prefab;
            let sprite: Laya.Sprite3D = LTRes.Get(ResUrl.prefab_url(prefabName));
            if (sprite) {
                SceneManager.instance.initNode(sprite, node);
                parent.addChild(sprite);
                this.prefabs[prefabName] = this.prefabs[prefabName] || [];
                this.prefabs[prefabName].push(sprite);
            }
        }
        else {
            node = node as node;
            if (node.child) {
                let nodeSp = new Laya.Sprite3D();
                SceneManager.instance.initNode(nodeSp, node);
                parent.addChild(nodeSp);
                node.child.forEach((nodeChild: node | Prefab) => {
                    this._buildScene(nodeChild, nodeSp);
                })
            }
        }
    }


    private _getPrefabName(spArr: string[], node: node | Prefab) {
        if (node) {
            let prefabName = node['prefabName'];
            if (prefabName) {
                node = node as Prefab;
                if (spArr.indexOf(prefabName) < 0) {
                    spArr.push(prefabName);
                }
            }
            else {
                node = node as node;
                if (node.child) {
                    node.child.forEach((nodeChild: node | Prefab) => {
                        this._getPrefabName(spArr, nodeChild as any);
                    });
                }
            }
        }
    }
}